#ifndef __V_STACK_H__
#define __V_STACK_H__

#ifdef __cplusplus
extern "C" {
#endif

#include "../common/v_lib_type.h"

typedef struct v_node  v_stack_node_t;
typedef struct v_node* v_stack_node_ptr_t;

struct v_stack {
    uint32_t size;
    v_stack_node_t* top;
    v_data_ptr_t null_data_ptr;     //当 stack 为空时， top 节点的数据指针指向 null_data_ptr
};

typedef struct v_stack v_stack_t;
typedef struct v_stack* v_stack_ptr_t;

/**
 * @brief 创建一个栈容器
 *
 * @param type_size : 容器中元素类型的size
 *
 * @return 返回容器的地址
 */
v_stack_ptr_t v_stack_create(uint32_t type_size);

/**
 * @brief 删除一个栈容器
 *
 * @param stack : 容器的地址
 *
 * @return NULL
 */
void v_stack_destroy(v_stack_ptr_t stack);

/**
 * @brief 向栈顶推送一个元素
 *
 * @param stack : 容器地址
 * @param data_ptr : 推送元素地址
 * @param data_size : 推送元素的数据
 * @param copy_data : 自定义copy函数, 默认memcpy
 *
 * @return 1 : OK , 
 *         0 : ERROR , 
 *        -2 : OVERFLOW
 */
vlib_status_t v_stack_push(v_stack_ptr_t stack, v_data_ptr_t data_ptr, uint32_t data_size, copy_data_f copy_data);

/**
 * @brief 栈顶元素出栈
 *
 * @param stack : 容器的地址
 *
 * @return 1 : OK , 
 *         0 : ERROR , 
 *         -2 : OVERFLOW
 */
vlib_status_t v_stack_pop(v_stack_ptr_t stack);

/**
 * @brief 清空容器
 *
 * @param stack : 容器地址
 *
 * @return NULL
 * 注意: 指针类型的容器慎用, 只将指针变量释放, 可能会造成内存泄露
 */
void v_stack_clear(v_stack_ptr_t stack);

/**
 * @brief 获取容器元素个数
 *
 * @param stack : 容器地址
 *
 * @return 元素个数
 */
uint32_t v_stack_size(v_stack_ptr_t stack);

/**
 * @brief 判断栈容器是否为空
 *
 * @param stack : 容器地址
 *
 * @return true : 容器为空
 *         flase : 容器不为空
 */
bool v_stack_empty(v_stack_ptr_t stack);

/**
 * @brief 获取容器栈顶元素数据
 *
 * @param stack : 容器地址
 *
 * @return 栈顶元素数据地址
 */
v_data_ptr_t v_stack_top(v_stack_ptr_t stack);

#ifdef __cplusplus
} /*extern "C"*/
#endif

#endif  /* __V_STACK_H__ */
